#include "snake_scene.h"
#include <iostream>
#include <graphics.h>
#include <tchar.h>
#include <string>
#define VK_P 0x50
#define VK_R 0x52
#define VK_W 0x57
#define VK_S 0x53
#define VK_A 0x41
#define VK_D 0x44


SnakeScene::SnakeScene(const std::string& name, int screenWidth, int screenHeight, int gridSize)
    : Scene(name), score(0), screenWidth(screenWidth), screenHeight(screenHeight), gridSize(gridSize),
    food(screenWidth, screenHeight, gridSize), snake(screenWidth, screenHeight, gridSize),
    gameOver(false), paused(false), moveTimer(0.0f), keyProcessed(false)
{
    inputHandler = new InputHandler(); // 初始化输入处理器
}

void SnakeScene::OnCreate() {
    std::cout << "SnakeScene created." << std::endl;
    setlinecolor(BLACK);
    setfillcolor(RED);
}

void SnakeScene::OnDestroy() {
    delete inputHandler; // 释放输入处理器
    std::cout << "SnakeScene destroyed." << std::endl;
}

void SnakeScene::OnActivate() {
    std::cout << "SnakeScene activated." << std::endl;
    gameOver = false;
    paused = false;
    score = 0;
    moveTimer = 0.0f;
    snake = Snake(screenWidth, screenHeight, gridSize);
    food.respawn();
}

void SnakeScene::OnDeactivate() {
    std::cout << "SnakeScene deactivated." << std::endl;
}

void SnakeScene::Update(float deltaTime) {
    inputHandler->update(); // 更新输入状态

    if (gameOver) {
        if (inputHandler->isKeyDown(VK_R) && !keyProcessed) {
            // 重新开始游戏
            snake = Snake(screenWidth, screenHeight, gridSize);
            food.respawn();
            score = 0;
            gameOver = false;
            paused = false;
            moveTimer = 0.0f;
            keyProcessed = true;
        }
        else if (inputHandler->isKeyUp(VK_R)) {
            keyProcessed = false;
        }
        return;
    }

    if (paused) {
        if (inputHandler->isKeyDown(VK_P) && !keyProcessed) {
            paused = false;
            keyProcessed = true;
        }
        else if (inputHandler->isKeyUp(VK_P)) {
            keyProcessed = false;
        }
        return;
    }

    // 暂停/恢复游戏
    if (inputHandler->isKeyDown(VK_P) && !keyProcessed) {
        paused = true;
        keyProcessed = true;
    }
    else if (inputHandler->isKeyUp(VK_P)) {
        keyProcessed = false;
    }

    // 改变蛇的移动方向，防止180度转弯
    if (inputHandler->isKeyDown(VK_W) && snake.getDirection() != 2 && !keyProcessed) {
        snake.changeDirection(0);
        keyProcessed = true;
    }
    else if (inputHandler->isKeyUp(VK_W)) {
        keyProcessed = false;
    }

    if (inputHandler->isKeyDown(VK_D) && snake.getDirection() != 3 && !keyProcessed) {
        snake.changeDirection(1);
        keyProcessed = true;
    }
    else if (inputHandler->isKeyUp(VK_D)) {
        keyProcessed = false;
    }

    if (inputHandler->isKeyDown(VK_S) && snake.getDirection() != 0 && !keyProcessed) {
        snake.changeDirection(2);
        keyProcessed = true;
    }
    else if (inputHandler->isKeyUp(VK_S)) {
        keyProcessed = false;
    }

    if (inputHandler->isKeyDown(VK_A) && snake.getDirection() != 1 && !keyProcessed) {
        snake.changeDirection(3);
        keyProcessed = true;
    }
    else if (inputHandler->isKeyUp(VK_A)) {
        keyProcessed = false;
    }

    // 移动计时器
    moveTimer += deltaTime;
    if (moveTimer >= 0.1f) {  // 每0.1秒移动一次
        snake.move();
        moveTimer = 0.0f;

        // 边界检查
        const auto& head = snake.getHead();
        if (head.getX() < 0 || head.getX() + gridSize > screenWidth ||
            head.getY() < 0 || head.getY() + gridSize > screenHeight) {
            gameOver = true;
            return;
        }

        // 食物碰撞检测
        if (snake.checkCollision(food.getCollisionBox())) {
            snake.grow();
            food.respawn();
            score++;
        }

        // 身体碰撞检测
        const auto& body = snake.getBody();
        for (size_t i = 3; i < body.size(); ++i) {
            if (snake.getHead().checkCollision(body[i])) {
                gameOver = true;
                return;
            }
        }
    }
}

void SnakeScene::Render() {
    cleardevice();

    // 游戏结束显示
    if (gameOver) {
        settextcolor(RED);
        settextstyle(48, 0, _T("Arial"));
        outtextxy(screenWidth / 2 - 100, screenHeight / 2 - 30, _T("GAME OVER"));

        settextstyle(24, 0, _T("Arial"));
        TCHAR scoreText[50];
        _stprintf_s(scoreText, _T("Score: %d"), score);
        outtextxy(screenWidth / 2 - 50, screenHeight / 2 + 30, scoreText);

        settextstyle(20, 0, _T("Arial"));
        outtextxy(screenWidth / 2 - 100, screenHeight / 2 + 80, _T("Press R to restart"));
        return;
    }

    // 暂停状态显示
    if (paused) {
        settextcolor(BLUE);
        settextstyle(36, 0, _T("Arial"));
        outtextxy(screenWidth / 2 - 60, screenHeight / 2 - 18, _T("PAUSED"));
    }

    // 绘制网格
    setlinecolor(RGB(220, 220, 220));
    for (int i = 0; i <= screenWidth; i += gridSize)
        line(i, 0, i, screenHeight);
    for (int j = 0; j <= screenHeight; j += gridSize)
        line(0, j, screenWidth, j);

    // 绘制蛇
    const auto& body = snake.getBody();
    setfillcolor(RED);
    for (const auto& part : body) {
        int x = static_cast<int>(part.getX());
        int y = static_cast<int>(part.getY());
        int width = static_cast<int>(part.getWidth());
        int length = static_cast<int>(part.getLength());
        fillrectangle(x, y, x + width, y + length);
    }

    // 绘制食物
    const auto& foodBox = food.getCollisionBox();
    setfillcolor(GREEN);
    int fx = static_cast<int>(foodBox.getX());
    int fy = static_cast<int>(foodBox.getY());
    int fwidth = static_cast<int>(foodBox.getWidth());
    int flength = static_cast<int>(foodBox.getLength());
    fillrectangle(fx, fy, fx + fwidth, fy + flength);

    // 显示分数
    settextcolor(BLACK);
    settextstyle(20, 0, _T("Arial"));
    TCHAR scoreText[20];
    _stprintf_s(scoreText, _T("Score: %d"), score);
    outtextxy(10, 10, scoreText);

    // 显示控制提示
    outtextxy(10, screenHeight - 30, _T("P: Pause/Resume"));
}